# -*- coding:utf-8 -*-

'''
Created on 01/07/2010

@author: sbrito
'''

from lib.utils import log
from scrapping.scrapping_functions import scrap_candidate, scrap_candidate_list
from persistence import persistence
from model.Candidate import Candidate
from etc import constants
from etc import config
import time

import loader

def scrap():
    # conexão com base de dados principal (que contém os dados de todos os candidatos)
    connection = persistence.connect(constants.GLOBAL_DATABASE_NAME)
    
    skip_list = []
    
    # a constante RECREATE_DATABASE indica se o scrapping deve ser feito integralmente ou apenas nos candidatos que ainda não foram obtidos
    if config.RECREATE_DATABASE:
        # cria/recria a base de dados
        persistence.create_tables(connection)
    else:
        try:
            # tenta obter os candidatos já salvos
            skip_list = persistence.get_candidate_ids(connection)
            print 'skip list', skip_list
        except:
            # falha caso ainda não exista base de dados e a cria.
            persistence.create_tables(connection)
    
    # loop principal iterando sobre a lista de estados
    for uf in config.UF_LIST:
        requests_for_uf = [] # lista de requisições para obter candidatos desse estado
        candidates = [] # lista de candidatos deste estado
        
        # loop iterando sobre a lista de tipos de cargo
        for type in config.TYPE_LIST:
            requests_for_uf.append({'uf': uf, 'type': type, 'url': generate_list_request(uf, type)})
        
        # loop iterando sobre as requisições para cada tipo de cargo
        for request in requests_for_uf:
            # scrap que retorna lista de ID's de todos os candidatos deste estado para o cargo
            candidate_list = loader.load_and_scrap(request['url'], scrap_candidate_list)
            if candidate_list == None:
                log('can\'t scrap %s, %s' % (request['uf'], request['type']))
            else:
                # loop iterando sobre cada id de candidato
                for i, candidate_id in enumerate(candidate_list):
                    # descarta o scrapping para este candidato caso ele já tenha sido obtido
                    if candidate_id in skip_list:
#                       log('skipping %s' % candidate_id)
                        continue
                    
                    # delay entre requisições
                    if i > 0:
                        time.sleep(config.DELAY_BETWEEN_CANDIDATE_REQUESTS)
                    
                    log('scrapping candidate %s %s %s ' % (request['uf'], request['type'], candidate_id))
                    # resultado do scrapping em plain object
                    candidate_po = loader.load_candidate(generate_candidate_request(request['uf'], candidate_id), request['uf'], request['type'], candidate_id, scrap_candidate)
                    if candidate_po == None:
                        log('can\'t scrap candidate %s %s %s ' % (request['uf'], request['type'], candidate_id))
                    else:
                        # conversão de plain object para tipo Candidate
                        candidate = Candidate(candidate_po)
                        # inserção do candidato na lista de candidatos deste estado
                        candidates.append(candidate)
        # inserção de todos os candidatos deste estado na lista geral        
        persistence.insert_candidates(connection, candidates)
    
        # a constante INSERT_ON_STATE_DATABASE indica se haverão bases de dados separadas para cada estado
        if config.INSERT_ON_STATE_DATABASE:
            state_connection = persistence.connect(constants.STATE_DATABASE_NAME % uf)
            persistence.create_tables(state_connection)        
            # insere os candidatos na base de dados específica para o estado
            persistence.insert_candidates(state_connection, candidates)
            persistence.disconnect(state_connection)
        
    

    persistence.disconnect(connection)

def generate_list_request(uf, type):
    name = ''
    #situation = constants.CANDIDATE_SITUATION_ABLE
    situation = constants.CANDIDATE_SITUATION_ALL 
    return constants.URL_CANDIDATE_LIST % (name, uf, type, situation)

def generate_candidate_request(uf, candidate_id):
    return constants.URL_CANDIDATE_DETAIL % (candidate_id, uf)

if __name__ == "__main__":
    scrap()